﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FigureDraw.Graphic.GDIPlus
{
    public class GDIPlusJPEGGraphic : CommonGraphic
    {
        string filename;
        Image image;
        Graphics g;
        Pen p;

        public GDIPlusJPEGGraphic(string filename, MyPoint size)
        {
            this.filename = filename;

            Bitmap bm = new Bitmap((int)size.X, (int)size.Y);
            image = (Image)bm;

            g = Graphics.FromImage(image);
            p = new Pen(Color.Black);
        }

        override public void DrawLine(MyPoint p1, MyPoint p2, MyColorInfo strokeColor, double strokeWidth)
        {
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);
            g.DrawLine(p, (float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y);
        }

        override public void DrawRectangle(MyPoint position, MyPoint size, MyColorInfo strokeColor, double strokeWidth, MyColorInfo brushColor)
        {
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);

            if (brushColor != null)
                g.FillRectangle(new SolidBrush(Color.FromArgb(brushColor.R, brushColor.G, brushColor.B)),
                                (float)position.X, (float)position.Y, (float)size.X, (float)size.Y);

            g.DrawRectangle(p, (float)position.X, (float)position.Y, (float)size.X, (float)size.Y);
        }

        public override void DrawRoundedRectangle(MyPoint position, MyPoint size, MyColorInfo strokeColor, double strokeWidth, MyColorInfo brushColor)
        {
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);

            GraphicsPath gp = new GraphicsPath();

            float cornerRadius = 30;

            if ((cornerRadius > size.Y / 2) || (cornerRadius > size.X / 2))
                cornerRadius = (float)Math.Min(size.Y / 2, size.X / 2);

            if (cornerRadius > 0)
            {
                gp.AddArc((float)position.X, (float)position.Y, cornerRadius, cornerRadius, 180, 90);
                gp.AddArc((float)(position.X + size.X - cornerRadius), (float)position.Y, cornerRadius, cornerRadius, 270, 90);
                gp.AddArc((float)(position.X + size.X - cornerRadius), (float)(position.Y + size.Y - cornerRadius), cornerRadius, cornerRadius, 0, 90);
                gp.AddArc((float)position.X, (float)(position.Y + size.Y - cornerRadius), cornerRadius, cornerRadius, 90, 90);
                gp.AddLine((float)position.X, (float)(position.Y + size.Y - cornerRadius), (float)position.X, (float)(position.Y + cornerRadius / 2));

                if (brushColor != null)
                    g.FillPath(new SolidBrush(Color.FromArgb(brushColor.R, brushColor.G, brushColor.B)), gp);

                g.DrawPath(p, gp);
            }
        }

        override public void DrawEllipse(MyPoint position, MyPoint size, MyColorInfo strokeColor, double strokeWidth, MyColorInfo brushColor)
        {
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);

            if (brushColor != null)
                g.FillEllipse(new SolidBrush(Color.FromArgb(brushColor.R, brushColor.G, brushColor.B)), (float)position.X, (float)position.Y, (float)size.X, (float)size.Y);

            g.DrawEllipse(p, (float)position.X, (float)position.Y, (float)size.X, (float)size.Y);
        }

        public override void DrawText(MyPoint position, string text, double size, MyColorInfo strokeColor)
        {
            g.DrawString(text, new Font(new FontFamily("Tahoma"), (float)size), new SolidBrush(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B)), (float)position.X, (float)position.Y);
        }

        public override void DrawCurve(MyColorInfo strokeColor, double strokeWidth, MyPoint[] points)
        {
            //AdjustableArrowCap bigArrow = new AdjustableArrowCap((float)5, (float)5);
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);
            //p.CustomEndCap = bigArrow;

            PointF[] curvePoints = new PointF[points.Length];

            for (int i = 0; i < points.Length; i++)
                curvePoints[i] = new PointF((float)points[i].X, (float)points[i].Y);

            g.DrawCurve(p, curvePoints);
        }

        public override void DrawPolygon(MyColorInfo strokeColor, double strokeWidth, MyColorInfo brushColor, params MyPoint[] points)
        {
            p = new Pen(Color.FromArgb(strokeColor.R, strokeColor.G, strokeColor.B), (float)strokeWidth);

            PointF[] polygonPoint = new PointF[points.Length];

            for (int i = 0; i < points.Length; i++)
                polygonPoint[i] = new PointF((float)points[i].X, (float)points[i].Y);

            if (brushColor != null)
                g.FillPolygon(new SolidBrush(Color.FromArgb(brushColor.R, brushColor.G, brushColor.B)), polygonPoint);

            g.DrawPolygon(p, polygonPoint);
        }

        public override void DrawPicture(List<MyShape> shapes)
        {
            base.DrawPicture(shapes);
            image.Save(filename, ImageFormat.Jpeg);
            image.Dispose();
        }
    }
}
